package com.jingbit.dialog;

import android.app.Activity;
import android.media.AudioFormat;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.jingbit.utils.DateUtils;
import com.jingbit.utils.FileUtils;
import com.jingbit.widget.WaveView;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import tech.oom.idealrecorder.IdealRecorder;
import tech.oom.idealrecorder.StatusListener;

/**
 * author: jingbit
 * date: 2018/10/30
 */
public class RecorderDialog extends CustomBaseDialog {
    private TextView tv_time;
    private TextView tv_state;
    private WaveView waveView;
    private ImageView btn_record;
    private IdealRecorder idealRecorder;
    private IdealRecorder.RecordConfig recordConfig;
    private String recordName;
    private File recordFile;
    private boolean recording;
    private int seconds = 0;

    private Timer timer;
    @NonNull
//    private final LameNative mLame = new LameNative();
    private IRecordClickListener recordClickListener;
    private Activity activity;
    private FileOutputStream fos;

    public RecorderDialog(@NonNull Activity context) {
        super(context, R.style.CustomDialog);
        this.activity = context;
        idealRecorder = IdealRecorder.getInstance();
        idealRecorder.init(context);
        idealRecorder.setVolumeInterval(200);//最大音量
        idealRecorder.setMaxRecordTime(15 * 60 * 1000);//15分钟

        //Recorder的配置信息 采样率 采样位数
        recordConfig = new IdealRecorder.RecordConfig(MediaRecorder.AudioSource.MIC,
                IdealRecorder.RecordConfig.SAMPLE_RATE_22K_HZ, AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT);

        // 初始化 Lame
//        int initResult = mLame.init(IdealRecorder.RecordConfig.SAMPLE_RATE_22K_HZ, AudioFormat.CHANNEL_IN_MONO);
//        if (initResult != 0) {
//            // Log.e(TAG, "Lame init result: " + initResult);
//            throw new ExceptionInInitializerError("Lame init error.");
//        } else {
//            Log.d("jingbit", "Lame init success.");
//        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recorder);
        tv_time = findViewById(R.id.tv_time);
        tv_state = findViewById(R.id.tv_state);
        waveView = findViewById(R.id.waveView);
        btn_record = findViewById(R.id.btn_record);

        btn_record.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!recording) {
                    FileUtils.deleteFile(FileUtils.getFilePath());
                    recordFile = null;
                    try {
                        startRecord(".wav");
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                } else {
                    stopRecord();
                }
            }
        });

        findViewById(R.id.btn_cancel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopRecord();
                resetView(true);
                dismiss();
            }
        });
        findViewById(R.id.btn_okay).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (recordFile == null || !recordFile.exists()) {
                    Toast.makeText(activity, "请先录音！", Toast.LENGTH_LONG).show();
                    return;
                }
                stopRecord();
                resetView(true);
                dismiss();
                if (recordClickListener != null) {
                    recordClickListener.onRecord(recordFile.getAbsolutePath(), seconds);
                }
            }
        });
    }

    private void resetView(boolean init) {
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                btn_record.setImageResource(R.drawable.ic_record_nor);
                tv_time.setText(init ? "00:00:00" : tv_time.getText());
                waveView.setVisibility(init ? View.GONE : View.VISIBLE);
                tv_state.setText("点击录音");
            }
        });
    }

    public void showDialog(IRecordClickListener recordClickListener) {
        this.recordClickListener = recordClickListener;
        showDialog(Gravity.BOTTOM, R.style.AnimBottom, 1, 0);
    }

    public void showDialog(String recordName,IRecordClickListener recordClickListener) {
        this.recordName = recordName;
        this.recordClickListener = recordClickListener;
        showDialog(Gravity.BOTTOM, R.style.AnimBottom, 1, 0);
    }

    /**
     * 停止录音
     */
    private void stopRecord() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
        recording = false;
        idealRecorder.stop();
        try {
            fos.flush();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 开始录音
     */
    private void startRecord(String ext) throws FileNotFoundException {
        recordFile = FileUtils.getTempFile(getContext(),recordName, Environment.DIRECTORY_MUSIC, ext);
        fos = new FileOutputStream(recordFile);
        //如果需要保存录音文件  设置好保存路径就会自动保存  也可以通过onRecordData 回调自己保存  不设置 不会保存录音
        idealRecorder.setRecordFilePath(recordFile.getAbsolutePath());
        //设置录音配置 最长录音时长 以及音量回调的时间间隔
        idealRecorder.setRecordConfig(recordConfig);
        //设置录音时各种状态的监听
        idealRecorder.setStatusListener(statusListener);
        idealRecorder.start(); //开始录音
    }

    /**
     * 启用计时器功能
     */
    private void countDownTimer() {
        if (timer == null) {
            timer = new Timer();
        }
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                seconds++;
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tv_time.setText(DateUtils.getFormatHMS(seconds * 1000));
                    }
                });
            }
        }, 0, 1000);
    }

    /**
     * 录音状态监听回调
     */
    private StatusListener statusListener = new StatusListener() {
        @Override
        public void onStartRecording() {
            seconds = 0;
            recording = true;
            countDownTimer();
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    btn_record.setImageResource(R.drawable.ic_record_ing);
                    tv_state.setText("录音中");
                    waveView.setVisibility(View.VISIBLE);
                }
            });

        }

        @Override
        public void onRecordData(short[] data, int length) {
            for (int i = 0; i < length; i += 60) {
                waveView.addData(data[i]);
            }
            try {
                if (recordFile.getName().endsWith("wav")){
                    fos.write(FileUtils.toByteArray(data), 0, length);
                }
                else{
//                    byte[] lameBuffer = new byte[length];
//                    int ret = mLame.buffer(data, data, length, lameBuffer);
//                    if (ret > 0) {
//                        fos.write(lameBuffer, 0, length);
//                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.d("jingbit", "save err: " + e.getMessage());
            }
        }

        @Override
        public void onVoiceVolume(int volume) {
        }

        @Override
        public void onRecordError(int code, String errorMsg) {
            Toast.makeText(getContext(), "录音失败！", Toast.LENGTH_SHORT).show();
            resetView(true);
        }

        @Override
        public void onFileSaveFailed(String error) {
            Toast.makeText(getContext(), "文件保存失败", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onFileSaveSuccess(String fileUri) {
//            Toast.makeText(getContext(), "文件保存成功,路径是" + fileUri, Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onStopRecording() {
            recording = false;
            Log.d("MX-Teacher", "onStopRecording");
            resetView(false);
        }
    };

    public interface IRecordClickListener {
        public void onRecord(String filePath, int duration);
    }

}
